// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Copyright (c) 2006 by Lattice Semiconductor Corporation
// --------------------------------------------------------------------
//
// Permission:
//
//   Lattice Semiconductor grants permission to use this code for use
//   in synthesis for any Lattice programmable logic product.  Other
//   use of this code, including the selling or duplication of any
//   portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL or Verilog source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Lattice Semiconductor provides no warranty
//   regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//           
//                     Lattice Semiconductor Corporation
//                     5555 NE Moore Court
//                     Hillsboro, OR 97214
//                     U.S.A
//
//                     TEL: 1-800-Lattice (USA and Canada)
//                          503-268-8001 (other locations)
//
//                     web: http://www.latticesemi.com/
//                     email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
//  Project:           7:1 LVDS Video Interface
//  File:              serializer_fsm.v
//  Title:             serializer FSM
//  Description:       Serializer Finite State Machines used in Tx module
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// $Log: serializer_fsm.vhd,v $
// Revision 1.0  2006-09-25 19:47:15-07  jhsin
// Revision 1.1  2007-11-12  hchen
//
// --------------------------------------------------------------------
`timescale 1 ns/ 1 ps

`include "lvds_7_to_1_def.v"

module ser_fsm 
     (
      TXCLK,
      CLK,
      RST,
      tx_wr_state,
      tx_rd_state
   );

input        TXCLK;
input        CLK;
input        RST;
output [2:0] tx_wr_state;
output [3:0] tx_rd_state;  

   reg       start_flag;
   reg       read_enable;
   reg       resync;
   reg [2:0] fsm_write /* synthesis syn_encoding="sequential" */;
   reg [3:0] fsm_read /* synthesis syn_encoding="sequential" */;
   //pragma attribute fsm_write FSM_STATE "binary" 
   //pragma attribute fsm_read FSM_STATE "binary"  
   
   
   assign tx_wr_state = fsm_write;
   assign tx_rd_state = fsm_read;
   
   always @(posedge TXCLK or posedge RST)
   begin
      if (RST) begin
         start_flag <= 1'b0;
         read_enable <= 1'b0;
         fsm_write <= `TX_WA1;
      end else begin
         case (fsm_write)
            `TX_WA1 : begin
                         fsm_write <= `TX_WB1;
                         read_enable <= 1'b0;
                      end                         
            `TX_WB1 : begin
                         fsm_write <= `TX_WC1;
                         read_enable <= 1'b0;
                      end                         
            `TX_WC1 : begin
                         fsm_write <= `TX_WD1;
                         read_enable <= 1'b1;
                      end                         
            `TX_WD1 : begin
                         fsm_write <= `TX_WA2;
                         read_enable <= 1'b1;
                      end                         
            `TX_WA2 : begin
                         fsm_write <= `TX_WB2;
                         read_enable <= 1'b1;
                      end                         
            `TX_WB2 : begin
                         fsm_write <= `TX_WC2;
                         read_enable <= 1'b1;
                      end                         
            `TX_WC2 : begin
                         fsm_write <= `TX_WD2;
                         read_enable <= 1'b1;
                      end                         
            `TX_WD2 : begin
                         fsm_write <= `TX_WA1;
                         read_enable <= 1'b0;
                      end                         
         endcase
         
         if (resync == 1'b0)  
            start_flag <= 1'b1;            
         else if (resync == 1'b1 &&
                  (fsm_write == `TX_WA2 || fsm_write == `TX_WB2))  
            start_flag <= 1'b1;
         else if (resync == 1'b1) 
            start_flag <= 1'b0;   
            
      end
   end 
   
   always @(posedge CLK or posedge RST)
   begin
      if (RST) begin
         fsm_read <= `TX_RA1;
         resync <= 1'b1;
      end else 
         case (fsm_read)
            `TX_RA1 : if (start_flag == 1'b1 && read_enable == 1'b1) begin
                         fsm_read <= `TX_RB1;  
                         resync <= 1'b0; 
                      end else
                         resync <= 1'b1;                                       
            `TX_RB1 : fsm_read <= `TX_RC1;   
            `TX_RC1 : fsm_read <= `TX_RD1;                                      
            `TX_RD1 : fsm_read <= `TX_RE1;                                      
            `TX_RE1 : fsm_read <= `TX_RF1;                                      
            `TX_RF1 : fsm_read <= `TX_RG1;                                      
            `TX_RG1 : fsm_read <= `TX_RA2;                                      
            `TX_RA2 : fsm_read <= `TX_RB2;                                      
            `TX_RB2 : fsm_read <= `TX_RC2;                                      
            `TX_RC2 : fsm_read <= `TX_RD2;                                      
            `TX_RD2 : fsm_read <= `TX_RE2;                                      
            `TX_RE2 : fsm_read <= `TX_RF2;                                      
            `TX_RF2 : fsm_read <= `TX_RG2;                                      
            `TX_RG2 : fsm_read <= `TX_RA1;
         endcase
   end

endmodule
